package com.cea.papyrustest.uml.deletecommand;

import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Property;

import com.cea.papyrus.core.commands.PapyrusCommand;
import com.cea.papyrus.core.commands.UMLElementCreateCommand;
import com.cea.papyrus.core.commands.UMLElementDeleteCommand;

/**
 * Test class for {@link Property} creation command
 * @author Remi Schnekenburger
 */
public class PropertyDeleteCommandTest extends PapyrusCommandTest {

	private final static String NAME = "Property_0"; 
	
	private org.eclipse.uml2.uml.Class class_;
	private org.eclipse.uml2.uml.Interface interface_;
	private org.eclipse.uml2.uml.Association association;
	private org.eclipse.uml2.uml.Signal signal;
	private org.eclipse.uml2.uml.DataType dataType;
	
	private Property propertyAssociation;
	private Property propertyClass;
	private Property propertyDateType;
	private Property propertyInterface;
	private Property propertySignal;
	
	
	private PapyrusCommand papyrusCommandClass;
	private PapyrusCommand papyrusCommandInterface;
	private PapyrusCommand papyrusCommandAssociation;
	private PapyrusCommand papyrusCommandSignal;
	private PapyrusCommand papyrusCommandDataType;
	

	/**
	 * Default constructor
	 * @param name the name of the test case
	 */
	public PropertyDeleteCommandTest(String name) {
		super(name);	
	}

	protected void setUp() throws Exception {
		super.setUp();
		// creates basic elements
		this.papyrusCommand= new UMLElementCreateCommand(org.eclipse.uml2.uml.Class.class,model);
		stack.execute(papyrusCommand);
		this.class_ = (org.eclipse.uml2.uml.Class)((UMLElementCreateCommand)papyrusCommand).getElement();
		
		this.papyrusCommand= new UMLElementCreateCommand(org.eclipse.uml2.uml.Interface.class,model);
		stack.execute(papyrusCommand);
		this.interface_ = (org.eclipse.uml2.uml.Interface)((UMLElementCreateCommand)papyrusCommand).getElement();
		
		this.papyrusCommand= new UMLElementCreateCommand(org.eclipse.uml2.uml.Association.class,model);
		stack.execute(papyrusCommand);
		this.association = (org.eclipse.uml2.uml.Association)((UMLElementCreateCommand)papyrusCommand).getElement();
		
		this.papyrusCommand= new UMLElementCreateCommand(org.eclipse.uml2.uml.Signal.class,model);
		stack.execute(papyrusCommand);
		this.signal = (org.eclipse.uml2.uml.Signal)((UMLElementCreateCommand)papyrusCommand).getElement();
		
		this.papyrusCommand= new UMLElementCreateCommand(org.eclipse.uml2.uml.DataType.class,model);
		stack.execute(papyrusCommand);
		this.dataType = (org.eclipse.uml2.uml.DataType)((UMLElementCreateCommand)papyrusCommand).getElement();

		// creates properties
		this.papyrusCommandAssociation = new UMLElementCreateCommand(org.eclipse.uml2.uml.Property.class, this.association);
		stack.execute(papyrusCommandAssociation);
		propertyAssociation = (Property)((UMLElementCreateCommand)papyrusCommandAssociation).getElement();
		
		this.papyrusCommandClass = new UMLElementCreateCommand(org.eclipse.uml2.uml.Property.class, this.class_);
		stack.execute(papyrusCommandClass);
		propertyClass = (Property)((UMLElementCreateCommand)papyrusCommandClass).getElement();
		
		this.papyrusCommandDataType = new UMLElementCreateCommand(org.eclipse.uml2.uml.Property.class, this.dataType);
		stack.execute(papyrusCommandDataType);
		propertyDateType = (Property)((UMLElementCreateCommand)papyrusCommandDataType).getElement();
		
		this.papyrusCommandInterface = new UMLElementCreateCommand(org.eclipse.uml2.uml.Property.class, this.interface_);
		stack.execute(papyrusCommandInterface);
		propertyInterface = (Property)((UMLElementCreateCommand)papyrusCommandInterface).getElement();
		
		this.papyrusCommandSignal= new UMLElementCreateCommand(org.eclipse.uml2.uml.Property.class, this.signal);
		stack.execute(papyrusCommandSignal);
		propertySignal = (Property)((UMLElementCreateCommand)papyrusCommandSignal).getElement();
		
		// CREATES DELETE COMMANDS
		this.papyrusCommandAssociation = new UMLElementDeleteCommand(propertyAssociation, this.association);
		this.papyrusCommandClass = new UMLElementDeleteCommand(propertyClass, this.class_);
		this.papyrusCommandDataType = new UMLElementDeleteCommand(propertyDateType, this.dataType);
		this.papyrusCommandInterface = new UMLElementDeleteCommand(propertyInterface, this.interface_);
		this.papyrusCommandSignal= new UMLElementDeleteCommand(propertySignal, this.signal);
		
		
	}

	/* (non-Javadoc)
	 * @see com.cea.papyrustest.PapyrusCommandTest#testExecute()
	 */
	public void testExecute() {
		
		///////////////////////////////////////////////////////////////////////
		// CLASS
		///////////////////////////////////////////////////////////////////////
		// execute command
		stack.execute(papyrusCommandClass);
		assertNull("the property exist on class!", class_.getOwnedAttribute(NAME, null));
		
		// undo command
		stack.undo();
		Element clazz=class_.getOwnedAttribute(NAME, null);
		assertNotNull("the property is created on class",clazz);
		assertTrue("this is not a property",((clazz)instanceof Property));

		// redo command
		stack.redo();
		assertNull("the property exist on class!", class_.getOwnedAttribute(NAME, null));
		
		///////////////////////////////////////////////////////////////////////
		// INTERFACE
		///////////////////////////////////////////////////////////////////////
		// execute command
		stack.execute(papyrusCommandInterface);
		assertNull("the property exist on interface!", this.interface_.getOwnedAttribute(NAME, null));
		
		// undo command
		stack.undo();
		clazz=this.interface_.getOwnedAttribute(NAME, null);
		assertNotNull("the property is created on interface",clazz);
		assertTrue("this is not a property",((clazz)instanceof Property));

		// redo command
		stack.redo();
		assertNull("the property exist on interface!", this.interface_.getOwnedAttribute(NAME, null));
		
		///////////////////////////////////////////////////////////////////////
		// ASSOCIATION
		///////////////////////////////////////////////////////////////////////
		// asssociation are not well created yet
		// assocTest();
		
		///////////////////////////////////////////////////////////////////////
		// SIGNAL
		///////////////////////////////////////////////////////////////////////
		// execute command
		stack.execute(papyrusCommandSignal);
		assertNull("the property exist on signal!", signal.getOwnedAttribute(NAME, null));

		// undo command
		stack.undo();
		clazz=signal.getOwnedAttribute(NAME, null);
		assertNotNull("the property is created on signal",clazz);
		assertTrue("this is not a property",((clazz)instanceof Property));

		// redo command
		stack.redo();
		assertNull("the property exist on signal!", signal.getOwnedAttribute(NAME, null));

		///////////////////////////////////////////////////////////////////////
		// DATATYPE
		///////////////////////////////////////////////////////////////////////
		// execute command
		stack.execute(papyrusCommandDataType);
		assertNull("the property exist on datatype!", this.dataType.getOwnedAttribute(NAME, null));

		// undo command
		stack.undo();
		clazz=this.dataType.getOwnedAttribute(NAME, null);
		assertNotNull("the property is created on datatype",clazz);
		assertTrue("this is not a property",((clazz)instanceof Property));

		// redo command
		stack.redo();
		assertNull("the property exist on datatype!", this.dataType.getOwnedAttribute(NAME, null));
	}
	
	/**
	 * Special test for properties on association
	 */
	public void assocTest() {
		// execute command
		stack.execute(papyrusCommandAssociation);
		assertNull("the property exist on association!", association.getMemberEnd(NAME, null));

		// undo command
		stack.undo();
		Property clazz=association.getMemberEnd(NAME, null);
		assertNotNull("the property is re-added to association",clazz);
		assertTrue("this is not a property",((clazz)instanceof Property));
		
		// redo command
		stack.redo();
		assertNull("the property exist on association!", association.getMemberEnd(NAME, null));

	}
	
	/* (non-Javadoc)
	 * @see com.cea.papyrustest.uml.deletecommand.PapyrusCommandTest#tearDown()
	 */
	@Override
	protected void tearDown() throws Exception {
		papyrusCommandAssociation= new UMLElementDeleteCommand(association, association.getOwner());
		papyrusCommandClass = new UMLElementDeleteCommand(class_, class_.getOwner());
		papyrusCommandDataType = new UMLElementDeleteCommand(dataType, dataType.getOwner());
		papyrusCommandInterface = new UMLElementDeleteCommand(interface_, interface_.getOwner());
		papyrusCommandSignal = new UMLElementDeleteCommand(signal, signal.getOwner());
		
		stack.execute(papyrusCommandAssociation);
		stack.execute(papyrusCommandClass);
		stack.execute(papyrusCommandDataType);
		stack.execute(papyrusCommandInterface);
		stack.execute(papyrusCommandSignal);
	}

}
